home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS14.ADF / Clocks / wClock / wClock.s < prev   
Text File  |  1989-01-28  |  10KB  |  311 lines

  1. * windowClock
  2. *
  3. *  This is a simple clock that displays the time in 24-hr mode to the nearest
  4. * minute. It will bring itself to the front anytime a new minute occurs.
  5. * It will not be overwritten when it becomes active or inactive as was true 
  6. * for some of it's ancestors.
  7. * Code size :             676 bytes
  8. * Minimum stack size :        1600 bytes
  9. * Memory used when running :    6968 bytes
  10.  
  11. *  I kept all code in this section so that it would all be loaded in the
  12. * same hunk and thus allow it to be refered to using x(PC) addressing.
  13. * Some rather inventive subroutine calling is used in the main loop to 
  14. * save a little time. The return address is kept in A4 and since it is
  15. * almost always the same this speeds up the process compared to BSR..RTS
  16.  
  17. * The majority of this code consists of initialization and termination code.
  18.  
  19. * I do not think it will work from the workbench as it is right now.
  20.  
  21. *  This file will assemble rather quickly since it does not use any include
  22. * files. It did at one time but that file was lost so I disassembled this 
  23. * file and then went through it and put in comments.
  24. *  I hope it is not hard to understand and that it will prove educational to
  25. * someone.
  26. *    Darrel Schneider
  27.  
  28. ***** open intuition library and store its pointer into D2 *****
  29.     LEA     IntuitionName(PC),A1
  30.     MOVEQ   #0,D0        ; load version number
  31.     MOVEA.L 4,A6        ; load exec library address
  32.     JSR     -$228(A6)    ; call OpenLibrary
  33.     TST.L   D0
  34.     BNE.S   *+4
  35.     RTS            ; FAIL: couldn't open intuition library
  36.     MOVE.L    D0,D2        ; store intuition library pointer
  37.  
  38. ***** open clock window *****
  39. ; I tried allocating and initializing the NewWindow structure
  40. ; on the stack in order to save a few bytes and it did BUT just a few.
  41. ; If it hadn't been for all the NULL fields it would have been larger.
  42.     ; use stack for the NewWindow structure
  43.     LINK    A2,#-$30
  44.     MOVEA.L A7,A1        ; load NewWindow pointer
  45.     MOVEQ   #$B,D0        ; loop count
  46.     ; this loop clears the NewWindow structure
  47.     CLR.L   (A1)+
  48.     DBF     D0,*-2
  49.  
  50.     ADDQ.B  #1,-(A1)    ; make it a WBENCHSCREEN
  51.     MOVEA.L A7,A1        ; load NewWindow pointer
  52.     MOVE.L  #$1F20000,(A1)+    ; left edge = $1f2, top edge = 0
  53.     MOVE.L  #$56000A,(A1)+    ; Width = $56,     Height = $A
  54.     NOT.W   (A1)+        ; default pens (-1)
  55.     MOVE.L  #$C0200,(A1)+    ; IDCMPflags = CLOSEWINDOW!ACTIVEWINDOW!INACTIVEWINDOW
  56.     MOVE.L  #$3000A,(A1)+    ; flags = WINDOWCLOSE!SMART_REFRESH!WINDOWDRAG!NOCAREREFRESH!RMBTRAP
  57.     MOVEA.L A7,A0        ; load NewWindow pointer
  58.  
  59.     EXG     D2,A6
  60.     JSR     -$CC(A6)    ; call OpenWindow
  61.     EXG     D2,A6
  62.  
  63.     UNLK    A2        ; discard the NewWindow structure
  64.     TST.L   D0
  65.     BEQ.L   FailOpenWindow
  66. WindowOpened:
  67.     MOVE.L  D0,A3        ; store window pointer
  68.     ; get ClockWindow->UserPort->mp_SigBit into D0
  69.     MOVEA.L $56(A3),A0    ; A0 = ClockWindow->UserPort
  70.     MOVEQ   #0,D0
  71.     MOVE.B  $F(A0),D0    ; D0 = the ClockWindow's mp_SigBit
  72.     MOVEQ   #1,D4
  73.     LSL.L   D0,D4        ; D4 = windowSigs
  74.     MOVE.L  D4,D7        ; D7 = waitFlags
  75.  
  76. ***** create timer port *****
  77.     ; get a signal bit
  78.     MOVEQ   #-1,D0
  79.     JSR     -$14A(A6)    ; call AllocSignal
  80.     MOVE.L  D0,D3        ; D3 = sigBit
  81.     BMI.S   FailCreateTimer1
  82.  
  83.     ; alloc port structure
  84.     MOVEQ   #$22,D0        ; size of structure
  85.     MOVE.L  #$10001,D1    ; memory type = CLEAR and PUBLIC
  86.     JSR     -$C6(A6)    ; call AllocMem
  87.     MOVE.L  D0,D5        ; D5 = timer Port
  88.     BNE.S   SkipFailCode
  89.     ; AllocMem failed
  90.     MOVE.L  D3,D0
  91.     JSR     -$150(A6)    ; call FreeSignal
  92.     BRA.S   FailCreateTimer2
  93. SkipFailCode:
  94.     ; fill port fields
  95.     MOVEA.L D5,A2
  96.     ADDQ.L  #8,A2        ; A2 now points to the LN_TYPE field        
  97.     MOVE.W  #$400,(A2)+    ; LN_TYPE = NT_MSGPORT, LN_PRI = 0
  98.     LEA    TimerPortName(PC),A0
  99.     MOVE.L  A0,(A2)+    ; LN_NAME = address of timer port name
  100.     MOVE.W  D3,(A2)+    ; MP_FLAGS = (#PA_SIGNAL=0), MP_SIGBIT = sigBit
  101.     MOVEQ   #0,D0
  102.     MOVEA.L D0,A1
  103.     JSR     -$126(A6)    ; call FindTask ( 0 arg means this task)
  104.     MOVE.L  D0,(A2)        ; MP_SIGTASK = pointer to found task
  105.  
  106.     BRA.S   SkipFailSection
  107.  
  108. ********** FAILURE SECTION ************
  109. ClosedWindow:
  110.     ; abort any standing timer request
  111.     MOVEA.L A5,A1
  112.     ; ABORTIO System Macro
  113.         MOVE.L  A6,-(A7)
  114.         MOVEA.L $14(A1),A6
  115.         JSR     -$24(A6)    
  116.         MOVEA.L (A7)+,A6
  117.     ; close timer device
  118.     MOVEA.L A5,A1
  119.     JSR     -$1C2(A6)    ; call CloseDevice
  120.     ; deallocate timeRequest structure
  121.     MOVEQ   #-1,D6
  122.     MOVE.B  D6,8(A5)
  123.     MOVE.L  D6,$14(A5)
  124.     MOVE.L  D6,$18(A5)
  125.     MOVEA.L A5,A1
  126.     MOVEQ   #$28,D0
  127.     JSR     -$D2(A6)    ; call FreeMem
  128.  
  129. FailOpenDevice:
  130. FailTimeRequestAlloc:
  131.     ; close timer port
  132.     MOVEA.L D5,A1
  133.     JSR     -$168(A6)    ; call RemPort
  134.     MOVEA.L D5,A2
  135.     ; D6 = -1
  136.     MOVE.B  D6,$A(A2)
  137.     MOVE.L  D6,(A2)
  138.     MOVE.L  (SP)+,D0    ; get the sigBit
  139.     JSR     -$150(A6)    ; call FreeSignal
  140.     MOVEA.L D5,A1
  141.     MOVEQ   #$22,D0
  142.     JSR     -$D2(A6)    ; call FreeMem
  143.  
  144. FailCreateTimer2:
  145. FailCreateTimer1:
  146.     MOVEA.L A3,A0
  147.     EXG     D2,A6
  148.     JSR     -$48(A6)    ; call CloseWindow
  149.     EXG    D2,A6
  150.  
  151. FailOpenWindow:
  152.     MOVEA.L    D2,A1        ; Intuition Library
  153.     JSR    -$19E(A6)    ; call CloseLibrary
  154.  
  155.     MOVEQ   #0,D0        ; this is the return value
  156.     RTS
  157.  
  158. ********* FAILURE END **********
  159.  
  160. SkipFailSection:
  161.     ; add the port
  162.     MOVEA.L D5,A1
  163.     JSR     -$162(A6)    ; call AddPort
  164.  
  165. ***** use the timer port sigBit(D3) to set the timeOutSig(D6) *****
  166.     MOVE.L  D3,D0
  167.     MOVE.L    D3,-(SP)    ; save the sigBit
  168.     MOVEQ   #1,D6
  169.     LSL.L   D0,D6
  170.     OR.L    D6,D7        ; update the waitFlags
  171.  
  172. ***** initialize timeRequest structure *****
  173.     MOVEQ   #$28,D0        ; D0 = IOTV_SIZE
  174.     MOVE.L  #$10001,D1    ; memory type = clear it, and public
  175.     JSR     -$C6(A6)    ; call AllocMem
  176.     TST.L   D0
  177.     BEQ.S   FailTimeRequestAlloc
  178.     MOVEA.L D0,A5        ; A5 = timeRequest
  179.     MOVE.W  #$500,8(A5)    ; LN_TYPE = NT_MESSAGE(5), LN_PRI = 0
  180.     MOVE.L  D5,$E(A5)    ; MN_REPLYPORT = timerPort
  181.                 ; AllocMem set to zero the IO_FLAGS, IO_ERROR fields
  182.  
  183. ***** open vblank timer device *****
  184.     LEA     TimerName(PC),A0    ; A0 = timer name
  185.     MOVEA.L A5,A1        ; A1 = timeRequest
  186.     MOVEQ   #1,D0        ; D0 = UNIT_VBLANK(1)
  187.     MOVEQ   #0,D1
  188.     JSR     -$1BC(A6)    ; call OpenDevice
  189.     TST.L   D0
  190.     BNE.S   FailOpenDevice
  191.     MOVE.W  #9,$1C(A5)    ; IO_COMMAND = TR_ADDREQUEST(9)
  192.  
  193. ***** initialize main loop *****
  194.     LEA     buffer(PC),A2    ; A2 = bufferPTR
  195.     LEA    InitMainLoop(PC),A4
  196.     BRA.S   InitializeTime
  197. InitMainLoop:    
  198.     LEA    WhileMoreMessages(PC),A4
  199. MainLoop:
  200.     MOVE.L  D7,D0        ; D0 = waitFlags
  201.     JSR     -$13E(A6)    ; call Wait
  202.     MOVE.L  D0,D3        ; save what woke the Wait up into D3
  203.     AND.L   D6,D0        ; was it the timeoutSig(D6)?
  204.     BEQ.S   isItAWindowSig    ; if it wasn't branch 
  205.     BRA.S   SetAndPrintTime 
  206. isItAWindowSig:
  207.     AND.L   D4,D3        ; was what woke the Wait up a windowSig(D4)?
  208.     BEQ.S   MainLoop    ; if not restart the main loop
  209.     ; keep doing the loop While there are window messages
  210. WhileMoreMessages:
  211.     MOVEA.L $56(A3),A0    ; A0 = window's UserPort
  212.     JSR     -$174(A6)    ; call GetMsg
  213.     TST.L   D0        ; D0 = message
  214.     BEQ.S   MainLoop    ; no more messages so start Waiting
  215.     MOVEA.L D0,A1
  216.     MOVE.W  $16(A1),-(A7)    ; save the messages im_Class
  217.     JSR     -$17A(A6)    ; call ReplyMessage
  218.     CMPI.W  #$200,(A7)+    ; was the message type CLOSEWINDOW? 
  219.     BEQ.L   ClosedWindow    ;  Yes so branch to termination code.
  220.                 ;  No so refresh the window by printing the time.
  221.     ; falls through to PrintTime
  222. ************************************
  223. PrintTime:
  224.     MOVEA.L $32(A3),A0    ; window's RPort
  225.     LEA     Date_Text(PC),A1    ; Date_Text structure
  226.     MOVEQ   #0,D0
  227.     MOVEQ   #0,D1
  228.     EXG     D2,A6
  229.     JSR     -$D8(A6)    ; call PrintIText
  230.     MOVEA.L A3,A0
  231.     JSR     -$138(A6)    ; call WindowToFront
  232.     EXG     D2,A6
  233.     JMP    (A4)        ; normally jumps to WhileMoreMessages
  234.  
  235. *****************************
  236. SetAndPrintTime:
  237.     MOVEA.L D5,A0        ; get message form timer port
  238.     JSR     -$174(A6)    ; call GetMsg
  239. InitializeTime:
  240.     ; initialize the buffer
  241.     MOVE.L  #$2030303A,(A2)+    ; buffer[0-3] = " 00:"
  242.     MOVE.L  #$30302000,(A2)        ; buffer[4-7] = "00 "0
  243.     ; set the timeRequest to wait for a minute
  244.     MOVE.W  #$3B,$22(A5)        ; TV_SECS = $3B(59 seconds)
  245.     MOVE.L  #$F423F,$24(A5)        ; TV_MICRO= MICRO_PER_SEC-1
  246.     ; get the current time. It will be on the stack
  247.     SUBQ.L  #4,A7    
  248.     LEA     (A7),A1        ; address of micros
  249.     SUBQ.L  #4,A7
  250.     LEA     (A7),A0        ; address of seconds
  251.     EXG     D2,A6
  252.     JSR     -$54(A6)    ; call CurrentTime
  253.     EXG     D2,A6
  254.  
  255.     MOVE.L  (A7)+,D0    ; secs
  256.     MOVE.L  (A7)+,D1    ; micros
  257.     SUB.L   D1,$24(A5)    ; subtract micros from TV_MICRO
  258.     CLR.W   -(A7)        ; push a zero word onto the stack => AM
  259.     DIVU    #-$5740,D0    ; secs/#secs_in_12hrs
  260.     LSR.B   #1,D0        ; test least sig. bit by shifting into C bit
  261.     BCC.S   AM
  262.     ; it is PM
  263.     MOVE.W  #$C,(A7)    ; top of stack now 12 => PM
  264. AM:
  265.     SWAP    D0        ; lower half of D0 = #of secs in the half day
  266.     MOVE.L  D0,D1        ; save D0 into D1
  267.     MOVEQ   #0,D0        
  268.     MOVE.W  D1,D0        ; 
  269.     DIVU    #$3C,D0        ; #of_secs_in_half_day/60
  270.     MOVE.W  D0,-(A7)    ; save the #of minutes*hrs in the half day
  271.     SWAP    D0        ; D0.W = # of secs in the minute
  272.     SUB.W   D0,$22(A5)    ; subtract this from the TV_SECS
  273.     ; start the timer running
  274.     MOVEA.L A5,A1
  275.     JSR     -$1CE(A6)    ; call SendIO
  276.  
  277.     ; figure out what time it is and load it in the buffer
  278.     MOVEQ   #0,D0
  279.     MOVE.W  (A7)+,D0    ; D0 has # of minutes*hrs in half day
  280.     DIVU    #$3C,D0        ; divide it by 60; rem = minutes, quot = hrs
  281.     MOVEQ   #0,D1        
  282.     MOVE.W  (A7)+,D1    ; D1 = (0=AM), (12=PM)
  283.     ADD.W   D0,D1        ; add quot to D1 giving # of hrs in the day
  284.     SWAP    D0        ; get the rem = minutes
  285.     EXT.L   D0
  286.     DIVU    #$A,D0        ; divide by 10; rem = ones digit, quot = tens digit
  287.     ADD.B   D0,(A2)+    ; add tens digit to buffer[4]
  288.     SWAP    D0
  289.     ADD.B   D0,(A2)        ; add ones digit to buffer[5]
  290.     DIVU    #$A,D1        ; divide hours by 10; rem = ones digit, quot = tens digit
  291.     SUBQ.L  #4,A2        ; set bufferPTR to buffer[1]
  292.     ADD.B   D1,(A2)+    ; add tens digit to buffer[1]
  293.     SWAP    D1
  294.     ADD.B   D1,(A2)        ; add ones digit to buffer[2]
  295.     SUBQ.L  #2,A2        ; set bufferPTR to buffer[0]
  296.     BRA.L   PrintTime    ; PrintTime will return
  297. **********************************************************
  298. TimerPortName:
  299.     DC.B    'timer',0
  300. TimerName:
  301.     DC.B    'timer.device',0,0
  302. IntuitionName:
  303.     DC.B    'intuition.library',0
  304. Date_Text:
  305.     DC.B    1,0,1,0
  306.     DC.W    29,1
  307.     DC.L    0,buffer,0
  308. buffer:
  309.     DS.B    8
  310.  
  311.